package com.noovo.comport.remoteserver;

import java.util.HashMap;

import com.noovo.comport.aidl.IComCallback;
import com.noovo.comport.aidl.IComService;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;

public abstract class RemoteComHelper {
	private Context mContext;
	private HashMap<String, Integer> nameMap = new HashMap<String, Integer>();
	private boolean RemoteService_NeedConnect = false;
	private boolean isConnected = false;
	private IComCallback mIComCallback = new IComCallback.Stub() {

		@Override
		public void onComCallback(String comName, byte[] data) throws RemoteException {
			MessageCall(comName, data);
		}
	};
	private IComService mIComService;
	private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			isConnected = true;
			mIComService = IComService.Stub.asInterface(service);
			try {
				mIComService.registerComCallback(mIComCallback);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			onComPortServiceConnected();
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			isConnected = false;
			if (RemoteService_NeedConnect) {
				onResume();
			}
			onComPortServiceDisconnected();
		}
	};

	public RemoteComHelper(Context context) {
		mContext = context;
	}
	
	public boolean isConnected(){
		return isConnected;
	}

	/**
	 * connect remote comport service
	 */
	public void onResume() {
		RemoteService_NeedConnect = true;
		Intent intent = new Intent("com.noovo.comport.remoteserver");
		intent.setClassName("com.noovo.comport", "com.noovo.comport.remoteserver.RemoteComService");
		mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}

	/**
	 * unconnect remote comport service
	 */
	public void onPause() {
		RemoteService_NeedConnect = false;
		if (mIComService != null) {
			try {
				mIComService.unregisterComCallback();
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		mContext.unbindService(conn);
	}

	/**
	 * 
	 * @param port
	 *            value: 1, 2, 3, 4
	 * @param comName
	 *            set the name of the ComPort, such as "printer", "DVR" or any
	 *            string you like
	 * @param baudRate
	 *            set the baudrate of the
	 * @param databits
	 *            avalible values: 7 or 8
	 * @param stopbits
	 *            avalible values: 0 or 1
	 * @param parity
	 *            avalible values: 'N' 'n' 'E' 'e' 'O' 'o'        
	 */
	public boolean setCom(int port, String comName, int baudrate, int databits, int stopbits, char parity) {
		nameMap.put(comName, port);
		if (mIComService != null) {
			try {
				mIComService.setCom(port, comName, baudrate, databits, stopbits, parity);
				return true;
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
	
	public boolean setCom(int port, String comName, int baudrate) {
		return setCom(port, comName, baudrate, 8, 1, 'N');
	}

	/**
	 * This message will be send once.
	 * 
	 * @param comName
	 * @param msg
	 */
	public boolean sendMessageOnce(String comName, byte[] msg) {
		if (nameMap.containsKey(comName)) {
			int port = nameMap.get(comName);
			if (mIComService != null) {
				try {
					mIComService.sendMessageOnce(port, msg);
					return true;
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}

	/**
	 * This message will be send
	 * 
	 * @param comName
	 * @param msg
	 * @param delay
	 */
	public boolean sendMessageLoop(String comName, byte[] msg, int delay) {
		if (nameMap.containsKey(comName)) {
			int port = nameMap.get(comName);
			if (mIComService != null) {
				try {
					mIComService.sendMessageLoop(port, msg, delay);
					return true;
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}

	public boolean stopSendMessage(String comName) {
		if (nameMap.containsKey(comName)) {
			int port = nameMap.get(comName);
			if (mIComService != null) {
				try {
					mIComService.stopSendMessage(port);
					return true;
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}
	
	public abstract void MessageCall(String comName, byte[] data);
	public abstract void onComPortServiceConnected();
	public abstract void onComPortServiceDisconnected();
}
